home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 101-125 / 118 / empire / src / source.zoo / cmd_map.d < prev    next >
Text File  |  1987-12-02  |  11KB  |  487 lines

  1. #include:util.g
  2. #empire.g
  3. #empfunc.g
  4.  
  5. /*
  6.  * near - return true if the addressed sector is near one owned by the given
  7.  *    country.
  8.  */
  9.  
  10. proc near(int r, c; uint user; *uint dir)bool:
  11.     Sector_t s;
  12.     uint dummy;
  13.     bool noDir;
  14.  
  15.     if dir = nil then
  16.     noDir := true;
  17.     dir := &dummy;
  18.     else
  19.     noDir := false;
  20.     fi;
  21.     readSector(r, c + 1, s);
  22.     if s.s_owner = user and (noDir or s.s_quantity[it_military] ~= 0) then
  23.     dir* := 2;
  24.     true
  25.     else
  26.     readSector(r, c - 1, s);
  27.     if s.s_owner = user and (noDir or s.s_quantity[it_military] ~= 0) then
  28.         dir* := 6;
  29.         true
  30.     else
  31.         readSector(r + 1, c - 1, s);
  32.         if s.s_owner = user and
  33.             (noDir or s.s_quantity[it_military] ~= 0) then
  34.         dir* := 5;
  35.         true
  36.         else
  37.         readSector(r + 1, c, s);
  38.         if s.s_owner = user and
  39.             (noDir or s.s_quantity[it_military] ~= 0) then
  40.             dir* := 4;
  41.             true
  42.         else
  43.             readSector(r + 1, c + 1, s);
  44.             if s.s_owner = user and
  45.                 (noDir or s.s_quantity[it_military] ~= 0) then
  46.             dir* := 3;
  47.             true
  48.             else
  49.             readSector(r - 1, c - 1, s);
  50.             if s.s_owner = user and
  51.                 (noDir or s.s_quantity[it_military] ~= 0) then
  52.                 dir* := 7;
  53.                 true
  54.             else
  55.                 readSector(r - 1, c, s);
  56.                 if s.s_owner = user and
  57.                     (noDir or
  58.                      s.s_quantity[it_military] ~= 0) then
  59.                 dir* := 0;
  60.                 true
  61.                 else
  62.                 readSector(r - 1, c + 1, s);
  63.                 if s.s_owner = user and
  64.                     (noDir or
  65.                      s.s_quantity[it_military] ~= 0) then
  66.                     dir* := 1;
  67.                     true
  68.                 else
  69.                     false
  70.                 fi
  71.                 fi
  72.             fi
  73.             fi
  74.         fi
  75.         fi
  76.     fi
  77.     fi
  78. corp;
  79.  
  80. /*
  81.  * digit printing routines for mapping.
  82.  */
  83.  
  84. proc digit1(int x)void:
  85.  
  86.     write(Chout;
  87.     if x <= -10 then
  88.         -x / 10 + '0'
  89.     elif x < 0 then
  90.         '-'
  91.     else
  92.         x / 10 + '0'
  93.     fi
  94.     );
  95. corp;
  96.  
  97. proc digit2(int x)void:
  98.  
  99.     write(Chout; |x % 10 + '0');
  100. corp;
  101.  
  102. proc coords(int left, right; bool extraSpace)void:
  103.     int c;
  104.  
  105.     write(Chout; if extraSpace then "   " else "  " fi);
  106.     for c from left upto right do
  107.     write(Chout; ' ');
  108.     digit1(c);
  109.     if extraSpace then
  110.         write(Chout; ' ');
  111.     fi;
  112.     od;
  113.     writeln(Chout;);
  114.     write(Chout; if extraSpace then "   " else "  " fi);
  115.     for c from left upto right do
  116.     write(Chout; ' ');
  117.     digit2(c);
  118.     if extraSpace then
  119.         write(Chout; ' ');
  120.     fi;
  121.     od;
  122.     writeln(Chout;);
  123. corp;
  124.  
  125. /*
  126.  * doMap - part of cmd_map - called by scanning code
  127.  */
  128.  
  129. proc doMap(int r, c; Sector_t s)void:
  130.     SectorType_t desig;
  131.     char ch;
  132.  
  133.     desig := s.s_type;
  134.     ch := SectorChar[desig];
  135.     if ThisCountryNumber ~= DEITY and s.s_owner ~= ThisCountryNumber then
  136.     if not near(r, c, ThisCountryNumber, nil) then
  137.         ch := ' ';
  138.     elif s.s_owner ~= DEITY and desig ~= s_mountain then
  139.         ch := '?';
  140.     fi;
  141.     elif ThisCountryNumber = DEITY and desig = s_water then
  142.      ch := ' ';
  143.     fi;
  144.     write(Chout; ' ', ch);
  145. corp;
  146.  
  147. /*
  148.  * special routines called if we set the map hook.
  149.  */
  150.  
  151. proc mapCoords(int left, right)void:
  152.  
  153.     coords(left, right, false);
  154. corp;
  155.  
  156. proc mapRowStart(int r)void:
  157.  
  158.     digit1(r);
  159.     digit2(r);
  160. corp;
  161.  
  162. proc mapRowEnd(int r)void:
  163.  
  164.     write(Chout; ' ');
  165.     digit1(r);
  166.     digit2(r);
  167.     writeln(Chout;);
  168. corp;
  169.  
  170. proc mapEmpty()void:
  171.  
  172.     write(Chout; "  ");
  173. corp;
  174.  
  175. proc cmd_map()bool:
  176.     Sector_t s;
  177.  
  178.     if reqSectors("Enter sectors specification for map: ") then
  179.     setMapHook();
  180.     pretend(scanSectors(doMap), void);
  181.     true
  182.     else
  183.     false
  184.     fi
  185. corp;
  186.  
  187. proc cmd_route()bool:
  188.     [9] char
  189.     TRANS_LEFT  = ('^', ' ', ' ', ' ', 'v', '/', '<','\\', ' '),
  190.     TRANS_RIGHT = ('^', '/', '>','\\', 'v', ' ', ' ', ' ', ' ');
  191.     Sector_t s;
  192.     int left, right, top, bottom, r, c;
  193.     ushort trans;
  194.     ItemType_t what;
  195.     SectorType_t desig;
  196.  
  197.     if reqCmsgpob(&what, "Enter type of thing to map routes for: ") and
  198.         doSkipBlanks() and
  199.         reqBox(&top, &bottom, &left, &right,
  200.            "Enter sectors specification for route map: ") then
  201.     coords(left, right, true);
  202.     writeln(Chout;);
  203.     for r from top upto bottom do
  204.         digit1(r);
  205.         digit2(r);
  206.         write(Chout; ' ');
  207.         for c from left upto right do
  208.         readSector(r, c, s);
  209.         desig := s.s_type;
  210.         if ThisCountryNumber ~= DEITY and
  211.             s.s_owner ~= ThisCountryNumber then
  212.             write(Chout; "   ");
  213.         else
  214.             trans := s.s_direction[what];
  215.             write(Chout; TRANS_LEFT[trans], SectorChar[desig],
  216.               TRANS_RIGHT[trans]);
  217.         fi;
  218.         od;
  219.         write(Chout; ' ');
  220.         digit1(r);
  221.         digit2(r);
  222.         writeln(Chout;);
  223.     od;
  224.     writeln(Chout;);
  225.     coords(left, right, true);
  226.     true
  227.     else
  228.     false
  229.     fi
  230. corp;
  231.  
  232. /*
  233.  * doRadar -
  234.  *    given a position and a range (x 1000), do a radar scan from there.
  235.  */
  236.  
  237. proc doRadar(int rRow, rCol; uint rang; bool hasSonar)void:
  238.     uint MAX_RANGE = 20;
  239.     [MAX_RANGE * 2 + 1, MAX_RANGE * 2 + 1] char map;
  240.     [MAX_RANGE * 2 + 1, MAX_RANGE * 2 + 1] uint biggestShip;
  241.     Sector_t s;
  242.     Ship_t sh;
  243.     uint range1, rangeSq, distance, shipNumber, size;
  244.     int top, bottom, left, right, r, c;
  245.     SectorType_t desig;
  246.     char ch;
  247.  
  248.     range1 := min(MAX_RANGE, rang / 1000 + 1);
  249.     top := rRow - range1;
  250.     bottom := rRow + range1;
  251.     left := rCol - range1;
  252.     right := rCol + range1;
  253.     rangeSq := make(rang, ulong) * rang / (1000 * 1000);
  254.  
  255.     /* first, fill in the map with terrain values */
  256.  
  257.     for r from top upto bottom do
  258.     for c from left upto right do
  259.         distance := findDistance(r, c, rRow, rCol);
  260.         if distance <= rangeSq then
  261.         readSector(r, c, s);
  262.         desig := s.s_type;
  263.         if desig ~= s_mountain and s.s_owner ~= DEITY and
  264.             s.s_owner ~= ThisCountryNumber and
  265.             distance > rangeSq / 4 then
  266.             ch := '?';
  267.         else
  268.             ch := SectorChar[desig];
  269.         fi;
  270.         else
  271.         ch := ' ';
  272.         fi;
  273.         map[range1 + r - rRow, range1 + c - rCol] := ch;
  274.         biggestShip[range1 + r - rRow, range1 + c - rCol] := 0;
  275.     od;
  276.     od;
  277.  
  278.     /* next, fill in all ships that are in range */
  279.  
  280.     if World.w_shipNext ~= 0 then
  281.     for shipNumber from 0 upto World.w_shipNext - 1 do
  282.         readShip(shipNumber, sh);
  283.         if sh.sh_owner ~= DEITY then    /* wrecks don't show up */
  284.         r := unTransRow(ThisCountryNumber, sh.sh_row);
  285.         if r >= rRow + World.w_rows / 2 then
  286.             r := r - World.w_rows;
  287.         elif r <= rRow - World.w_rows / 2 then
  288.             r := r + World.w_rows;
  289.         fi;
  290.         c := unTransCol(ThisCountryNumber, sh.sh_col);
  291.         if c >= rCol + World.w_columns / 2 then
  292.             c := c - World.w_columns;
  293.         elif c <= rCol - World.w_columns / 2 then
  294.             c := c + World.w_columns;
  295.         fi;
  296.         distance := findDistance(r, c, rRow, rCol);
  297.         size := World.w_shipSize[sh.sh_type];
  298.         if sh.sh_type = st_submarine then
  299.             size := if hasSonar then 15 else 0 fi;
  300.         fi;
  301.         if distance <= make(rangeSq, ulong) * size * size / 1018 then
  302.             if sh.sh_type ~= st_submarine then
  303.             write(Chout; &Country[sh.sh_owner].c_name[0], ' ');
  304.             fi;
  305.             writeln(Chout; getShipName(sh.sh_type), " \#", shipNumber,
  306.                 " at ", r, ',', c);
  307.             r := range1 + r - rRow;
  308.             c := range1 + c - rCol;
  309.             if size > biggestShip[r, c] then
  310.             biggestShip[r, c] := size;
  311.             if map[r, c] = SectorChar[s_water] then
  312.                 map[r, c] := ShipChar[sh.sh_type] - 32;
  313.             fi;
  314.             fi;
  315.         fi;
  316.         fi;
  317.     od;
  318.     fi;
  319.  
  320.     /* now display the resulting map */
  321.  
  322.     coords(left, right, false);
  323.     writeln(Chout;);
  324.     for r from top upto bottom do
  325.     digit1(r);
  326.     digit2(r);
  327.     for c from left upto right do
  328.         write(Chout; ' ', map[range1 + r - rRow, range1 + c - rCol]);
  329.     od;
  330.     write(Chout; ' ');
  331.     digit1(r);
  332.     digit2(r);
  333.     writeln(Chout;);
  334.     od;
  335.     writeln(Chout;);
  336.     coords(left, right, false);
  337. corp;
  338.  
  339. proc cmd_radar()bool:
  340.     Sector_t s;
  341.     Ship_t sh;
  342.     int row, col;
  343.     uint shipNumber;
  344.     bool isShip;
  345.  
  346.     if reqSectorOrShip(&row, &col, &shipNumber, &isShip,
  347.         "Enter sector or ship to scan from: ") then
  348.     if isShip then
  349.         readShip(shipNumber, sh);
  350.         if sh.sh_owner ~= ThisCountryNumber then
  351.         err("that ship doesn't belong to you");
  352.         else
  353.         if updateShip(shipNumber, sh) then
  354.             writeShip(shipNumber, sh);
  355.         fi;
  356.         doRadar(unTransRow(ThisCountryNumber, sh.sh_row),
  357.             unTransCol(ThisCountryNumber, sh.sh_col),
  358.             World.w_shipRange[sh.sh_type] * sh.sh_efficiency,
  359.             sh.sh_type = st_destroyer or sh.sh_type =st_submarine);
  360.         fi;
  361.     else
  362.         accessSector(row, col, s);
  363.         if s.s_owner ~= ThisCountryNumber then
  364.         err("that sector doesn't belong to you");
  365.         elif s.s_type ~= s_radar then
  366.         err("that sector isn't a radar station");
  367.         else
  368.         doRadar(row, col, s.s_efficiency * World.w_radarFactor,
  369.             false);
  370.         fi;
  371.     fi;
  372.     true
  373.     else
  374.     false
  375.     fi
  376. corp;
  377.  
  378. proc cmd_weather()void:
  379.     int top, bottom, left, right, r, c, w;
  380.  
  381.     if reqBox(&top, &bottom, &left, &right, "Enter region to map: ") then
  382.     coords(left, right, false);
  383.     writeln(Chout;);
  384.     for r from top upto bottom do
  385.         digit1(r);
  386.         digit2(r);
  387.         for c from left upto right do
  388.         w := weather(transRow(r), transCol(c));
  389.         if w < -9 then
  390.             write(Chout; '-', -w - 10 + 'A');
  391.         elif w > 9 then
  392.             write(Chout; '+', w - 10 + 'A');
  393.         elif w > 0 then
  394.             write(Chout; '+', w);
  395.         else
  396.             write(Chout; w : 2);
  397.         fi;
  398.         od;
  399.         write(Chout; ' ');
  400.         digit1(r);
  401.         digit2(r);
  402.         writeln(Chout;);
  403.     od;
  404.     writeln(Chout;);
  405.     coords(left, right, false);
  406.     writeln(Chout; "Extreme low pressure center at ",
  407.         unTransRow(ThisCountryNumber, World.w_loRow / 4), ',',
  408.         unTransCol(ThisCountryNumber, World.w_loCol / 4),
  409.         ", extreme high at ",
  410.         unTransRow(ThisCountryNumber, World.w_hiRow / 4), ',',
  411.         unTransCol(ThisCountryNumber, World.w_hiCol / 4), '.');
  412.     fi;
  413. corp;
  414.  
  415. proc cmd_forecast()bool:
  416.     Sector_t s;
  417.     uint time, rang, range1, rangeSq, distance;
  418.     int top, bottom, left, right, wRow, wCol, r, c, wea;
  419.  
  420.     if reqSector(&wRow, &wCol, "Sector of weather station? ") and
  421.         doSkipBlanks() and
  422.         reqPosRange(&time, 127,
  423.             "How many half-hours in the future? ") then
  424.     accessSector(wRow, wCol, s);
  425.     if s.s_owner ~= ThisCountryNumber then
  426.         err("you don't own that sector");
  427.     elif s.s_type ~= s_weather then
  428.         err("sector isn't a weather station");
  429.     elif s.s_efficiency < 60 then
  430.         err("station isn't efficient enough for forecasting");
  431.     elif time > readQuan(s, it_civilians) then
  432.         err("not enough workers for that accurate a forecast");
  433.     else
  434.         weatherPreserve();
  435.         while time ~= 0 do
  436.         time := time - 1;
  437.         weatherStep();
  438.         od;
  439.         rang := make(s.s_efficiency, uint) * 70;
  440.         range1 := rang / 1000 + 1;
  441.         top := wRow - range1;
  442.         bottom := wRow + range1;
  443.         left := wCol - range1;
  444.         right := wCol + range1;
  445.         rangeSq := make(rang, ulong) * rang / (1000 * 1000);
  446.         coords(left, right, false);
  447.         writeln(Chout;);
  448.         for r from top upto bottom do
  449.         digit1(r);
  450.         digit2(r);
  451.         for c from left upto right do
  452.             if findDistance(r, c, wRow, wCol) <= rangeSq then
  453.             wea := weather(transRow(r), transCol(c));
  454.             if wea < -9 then
  455.                 write(Chout; '-', -wea - 10 + 'A');
  456.             elif wea > 9 then
  457.                 write(Chout; '+', wea - 10 + 'A');
  458.             elif wea > 0 then
  459.                 write(Chout; '+', wea);
  460.             else
  461.                 write(Chout; wea : 2);
  462.             fi;
  463.             else
  464.             write(Chout; "  ");
  465.             fi;
  466.         od;
  467.         write(Chout; ' ');
  468.         digit1(r);
  469.         digit2(r);
  470.         writeln(Chout;);
  471.         od;
  472.         writeln(Chout;);
  473.         coords(left, right, false);
  474.         writeln(Chout; "Extreme low pressure center at ",
  475.             unTransRow(ThisCountryNumber, World.w_loRow / 4), ',',
  476.             unTransCol(ThisCountryNumber, World.w_loCol / 4),
  477.             ", extreme high at ",
  478.             unTransRow(ThisCountryNumber, World.w_hiRow / 4), ',',
  479.             unTransCol(ThisCountryNumber, World.w_hiCol / 4), '.');
  480.         weatherRestore();
  481.     fi;
  482.     true
  483.     else
  484.     false
  485.     fi
  486. corp;
  487.